#include <GSLAM/core/Jvar.h>
#include <sockpp/tcp_acceptor.h>
#include <sockpp/tcp_connector.h>

using namespace std;
using namespace sv;
using namespace sockpp;

int main(){}


REGISTER_SVAR_MODULE(sockpp){
    Class<socket_initializer>("socket_initializer")
            .unique_construct<>();

    Class<stream_socket>("stream_socket")
            .def("is_connected",[](stream_socket* self){return (bool)*self;})
            .def("address",[](stream_socket* self){return inet_address(self->address()).to_string();})
            .def("peer_address",[](stream_socket* self){return inet_address(self->peer_address()).to_string();})
            .def("read",[](stream_socket* self,SvarBuffer buf){return (int)self->read((char*)buf.ptr(),buf.size());})
            .def("write",[](stream_socket* self,SvarBuffer buf){return (int)self->write(buf.ptr(),buf.size());})
            .def("read_until",[](stream_socket* self,SvarBuffer buf){
        int read=0;
        while(read < buf.size()){
//            std::cerr<<"Try to receive:"<<buf.size()-read<<std::endl;
            int received=(int)self->read((char*)buf.ptr()+read,buf.size()-read);
            if(received==0) break;
//            std::cerr<<"Received:"<<received<<std::endl;
            read+=received;
        }
        return read;
    })
    ;

    Class<tcp_acceptor>("tcp_acceptor")
            .unique_construct<int>()
            .def("accept",[](tcp_acceptor* self){return std::unique_ptr<stream_socket>(new stream_socket(self->accept()));})
            .def("address",[](tcp_acceptor* self){return self->address().to_string();});

    Class<tcp_connector>("tcp_connector")
            .def("__init__",[](std::string addr,int port){return std::unique_ptr<tcp_connector>(new tcp_connector({addr,(uint16_t)port}));})
            .def("is_connected",[](tcp_connector* self){return self->is_connected();})
            .def("last_error",&tcp_connector::last_error)
            .def("last_error_str",&tcp_connector::last_error_str)
            .def("read",[](tcp_connector* self,SvarBuffer buf){return (int)self->read((char*)buf.ptr(),buf.size());})
            .def("write",[](tcp_connector* self,SvarBuffer buf){return (int)self->write(buf.ptr(),buf.size());})
            .def("read_until",[](tcp_connector* self,SvarBuffer buf){
                int read=0;
                while(read < buf.size()){
                    int received=(int)self->read((char*)buf.ptr()+read,buf.size()-read);
                    if(received==0) break;
                    read+=received;
                }
                return read;
            })
    ;
}

EXPORT_SVAR_INSTANCE
